#include <iostream>
#include <string>
#include "user.pb.h"
#include "mprpcapplication.h"
#include "rpcprovider.h"
//Userservice原来是一个本地服务，提供了两个进程内的本地方法，Login和GetFriendLists
class UserService : public fixbug::UserServiceRpc // 使用在rpc服务的发布端的，即rpc服务的提供者
{
public:
    bool Login(std::string name, std::string pwd)
    {
        std::cout << "doing local service: Login" << std::endl;
        std::cout << "name:" << name << "  pwd:" << pwd << std::endl;
        return true;
    }

    bool Register(uint32_t id,std::string name,std::string pwd)
    {
        std::cout << "doing local service: Login" << std::endl;
        std::cout <<"id"<<id<< " name:" << name << "  pwd:" << pwd << std::endl;
        return true;
    }

    //重写基类UserServiceRpc的虚函数，下面这些方法都是框架直接调用的
    //RpcController是纯虚函数，携带着rpc方法调用过程中的一些状态信息
    void Login(::google::protobuf::RpcController *controller,
               const ::fixbug::LoginRequest *request,
               ::fixbug::LoginResponse *response,
               ::google::protobuf::Closure *done)
    {
        std::string name=request->name();
        std::string pwd=request->pwd();

        //做本地业务
        bool login_result=Login(name,pwd);//函数重载，参数和返回值不同

        //把响应写入 包括错误码 错误消息 返回值
        fixbug::ResultCode *code=response->mutable_result();
        code->set_errcode(0);//没有错误时，错误码置为0
        code->set_errmsg("");//没有错误时，错误码为空
        response->set_success(login_result);

        //执行回调操作 执行响应对象数据的序列化和网络发送（都是由框架来完成的）
        done->Run(); 
    }
    void Register(::google::protobuf::RpcController* controller,
        const ::fixbug::RegisterRequset* request,
        ::fixbug::RegisterResponse* response,
        ::google::protobuf::Closure* done)
        {
            uint32_t id=request->id();
            std::string name=request->name();
            std::string pwd=request->pwd();

            bool ret=Register(id,name,pwd);
            response->mutable_result()->set_errcode(0);
            response->mutable_result()->set_errmsg("");
            response->set_success(ret);
            done->Run();
        }
};

int main(int agrc,char** argv)
{
    //使用框架前，一般都需要先调用框架的初始化操作(做一些配置、日志的初始化)
    //以provider -i config.conf形式输入，从config.conf中读取网络服务器及配置中心的地址或者端口号
    MprpcApplication::Init(agrc,argv);//将来需要一些ip地址和端口号，这些不能写死，需要在环境变量中获取

    RpcProvider provider;//专门在框架上发布服务的,provider是一个rpc网络服务对象，将UserService对象发布到rpc节点上
    provider.NotifyService(new UserService());

    //启动一个rpc服务发布节点，Run以后，进程进入阻塞状态，等待远程的rpc调用请求
    provider.Run();
    return 0;
}